package com.liuyi.usercenterservice.job;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.liuyi.usercenterservice.common.RedisKey;
import com.liuyi.usercenterservice.entity.domain.User;
import com.liuyi.usercenterservice.mapper.UserMapper;
import com.liuyi.usercenterservice.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.scheduling.annotation.Scheduled;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author 刘燚
 * @version v1.0.0
 * @Description 推荐页面数据预热
 * @createDate：2024/6/29 00:51
 * @email limit2022@163.com
 */
@Configuration
@Slf4j
public class RecommendJob {
    @Resource
    RedisTemplate<String , Object> redisTemplate;
    @Resource
    RedissonClient redissonClient;
    @Resource
    UserMapper userMapper;
    @Scheduled(cron = "0 28 20 * * ? ")
    public void loadDataForRedis(){
        RLock lock = redissonClient.getLock(RedisKey.CACHE_LOCK_KEY);
        try {
            if (lock.tryLock(0L,-1L,TimeUnit.MILLISECONDS)){
                String keySub = RedisKey.RECOMMEND_KEY;
                ValueOperations<String, Object> opsForValue = redisTemplate.opsForValue();
                //region 获取最近活跃的用户做数据预热
                Date activeDate = Date.from(LocalDateTime.now().minusDays(7).atZone(ZoneId.systemDefault()).toInstant());
                QueryWrapper<User> queryWrapper = new QueryWrapper<>();
                queryWrapper.isNotNull("login_time")
                        .gt("login_time",activeDate);
                List<User> preUserList = userMapper.selectList(queryWrapper);
                //endregion
                for (User user : preUserList) {
                    List<User> records = getUsersByTags(user.getTags(), new Page<>(0, 20)).getRecords();
                    String key = keySub + user.getId();
                    try {
                        opsForValue.set(key,records,1, TimeUnit.DAYS);
                    } catch (Exception e) {
                        log.error(e.getMessage());
                        throw new RuntimeException(e);
                    }
                }
            }
        } catch (InterruptedException e) {
            log.error(e.getMessage());
            throw new RuntimeException(e);
        }finally {
            if (lock.isHeldByCurrentThread()){
                lock.unlock();
            }
        }
    }
    public Page<User> getUsersByTags(String tags, Page<User> page) {
        Gson gson = new Gson();
        Set<String> tagSet = gson.fromJson(tags, new TypeToken<Set<String>>() {
        }.getType());
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        for (String tag : tagSet) {
            queryWrapper.or().like("tags","%" + tag + "%");
        }
        return userMapper.selectPage(page, queryWrapper);
    }
}
